home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / amiga / viewers / ham8_jpg.lha / ham8-jpeg / Source / display24.c < prev    next >
C/C++ Source or Header  |  1992-12-20  |  19KB  |  948 lines

  1. /*
  2.  * display24.c Michael Saunby    M.Saunby@reading.ac.uk
  3.  *
  4.  * Release 1.1
  5.  *
  6.  * Display 24 bit RGB data using the Albert HAM8 screen.
  7.  */
  8.  
  9. #include <exec/memory.h>
  10. #include <libraries/dos.h>
  11. #include <libraries/dosextens.h>
  12. #include <intuition/intuition.h>
  13. #include <graphics/gfxbase.h>
  14. #include <graphics/displayinfo.h>
  15. #include <intuition/screens.h>
  16.  
  17. #include <clib/exec_protos.h>
  18. #include <clib/intuition_protos.h>
  19. #include <clib/graphics_protos.h>
  20.  
  21. #include <stdlib.h>
  22. #include "display24.h"
  23.  
  24. /* 
  25.  * Change USE_STD_COLOURS to 0 for ham only.  Faster but not as sharp. 
  26.  * More code could be disabled for greater speed.
  27.  */
  28. #define USE_STD_COLOURS 1
  29.  
  30. typedef UBYTE std_pal_type;
  31. static ULONG red_dist[9], green_dist[9], blue_dist[9];
  32. static UWORD standard_pens[48];
  33.  
  34.  
  35. /*
  36.  * The following defines set the standard palette colours.
  37.  * The __inline functions are used to compare these colours with the input
  38.  * colour.
  39.  *
  40.  * Greys
  41.  */
  42. #define STD_COLOUR_01 {0,0,0}
  43. static __inline ULONG 
  44. dist_fn_01 ()
  45. {
  46.   return (red_dist[0] + green_dist[0] + blue_dist[0]);
  47. }
  48.  
  49. #define STD_COLOUR_02 {32,32,32}
  50. static __inline ULONG 
  51. dist_fn_02 ()
  52. {
  53.   return (red_dist[1] + green_dist[1] + blue_dist[1]);
  54. }
  55.  
  56. #define STD_COLOUR_03 {64,64,64}
  57. static __inline ULONG 
  58. dist_fn_03 ()
  59. {
  60.   return (red_dist[2] + green_dist[2] + blue_dist[2]);
  61. }
  62.  
  63. #define STD_COLOUR_04 {96,96,96}
  64. static __inline ULONG 
  65. dist_fn_04 ()
  66. {
  67.   return (red_dist[3] + green_dist[3] + blue_dist[3]);
  68. }
  69.  
  70. #define STD_COLOUR_05 {128,128,128}
  71. static __inline ULONG 
  72. dist_fn_05 ()
  73. {
  74.   return (red_dist[4] + green_dist[4] + blue_dist[4]);
  75. }
  76.  
  77. #define STD_COLOUR_06 {160,160,160}
  78. static __inline ULONG 
  79. dist_fn_06 ()
  80. {
  81.   return (red_dist[5] + green_dist[5] + blue_dist[5]);
  82. }
  83.  
  84. #define STD_COLOUR_07 {192,192,192}
  85. static __inline ULONG 
  86. dist_fn_07 ()
  87. {
  88.   return (red_dist[6] + green_dist[6] + blue_dist[6]);
  89. }
  90.  
  91. #define STD_COLOUR_08 {224,224,224}
  92. static __inline ULONG 
  93. dist_fn_08 ()
  94. {
  95.   return (red_dist[7] + green_dist[7] + blue_dist[7]);
  96. }
  97.  
  98. #define STD_COLOUR_09 {255,255,255}
  99. static __inline ULONG 
  100. dist_fn_09 ()
  101. {
  102.   return (red_dist[8] + green_dist[8] + blue_dist[8]);
  103. }
  104.  
  105. /*
  106.  * reds
  107.  */
  108. #define STD_COLOUR_10 {64,0,0}
  109. static __inline ULONG 
  110. dist_fn_10 ()
  111. {
  112.   return (red_dist[2] + green_dist[0] + blue_dist[0]);
  113. }
  114.  
  115. #define STD_COLOUR_11 {128,0,0}
  116. static __inline ULONG 
  117. dist_fn_11 ()
  118. {
  119.   return (red_dist[4] + green_dist[0] + blue_dist[0]);
  120. }
  121.  
  122. #define STD_COLOUR_12 {192,0,0}
  123. static __inline ULONG 
  124. dist_fn_12 ()
  125. {
  126.   return (red_dist[6] + green_dist[0] + blue_dist[0]);
  127. }
  128.  
  129. #define STD_COLOUR_13 {255,0,0}
  130. static __inline ULONG 
  131. dist_fn_13 ()
  132. {
  133.   return (red_dist[8] + green_dist[0] + blue_dist[0]);
  134. }
  135.  
  136. /*
  137.  * greens
  138.  */
  139. #define STD_COLOUR_14 {0,64,0}
  140. static __inline ULONG 
  141. dist_fn_14 ()
  142. {
  143.   return (red_dist[0] + green_dist[2] + blue_dist[0]);
  144. }
  145.  
  146. #define STD_COLOUR_15 {0,128,0}
  147. static __inline ULONG 
  148. dist_fn_15 ()
  149. {
  150.   return (red_dist[0] + green_dist[4] + blue_dist[0]);
  151. }
  152.  
  153. #define STD_COLOUR_16 {0,192,0}
  154. static __inline ULONG 
  155. dist_fn_16 ()
  156. {
  157.   return (red_dist[0] + green_dist[6] + blue_dist[0]);
  158. }
  159.  
  160. #define STD_COLOUR_17 {0,255,0}
  161. static __inline ULONG 
  162. dist_fn_17 ()
  163. {
  164.   return (red_dist[0] + green_dist[8] + blue_dist[0]);
  165. }
  166.  
  167. /*
  168.  * blues
  169.  */
  170. #define STD_COLOUR_18 {0,0,64}
  171. static __inline ULONG 
  172. dist_fn_18 ()
  173. {
  174.   return (red_dist[0] + green_dist[0] + blue_dist[2]);
  175. }
  176.  
  177. #define STD_COLOUR_19 {0,0,128}
  178. static __inline ULONG 
  179. dist_fn_19 ()
  180. {
  181.   return (red_dist[0] + green_dist[0] + blue_dist[4]);
  182. }
  183.  
  184. #define STD_COLOUR_20 {0,0,192}
  185. static __inline ULONG 
  186. dist_fn_20 ()
  187. {
  188.   return (red_dist[0] + green_dist[0] + blue_dist[6]);
  189. }
  190.  
  191. #define STD_COLOUR_21 {0,0,255}
  192. static __inline ULONG 
  193. dist_fn_21 ()
  194. {
  195.   return (red_dist[0] + green_dist[0] + blue_dist[8]);
  196. }
  197.  
  198. /*
  199.  * red-greens
  200.  */
  201. #define STD_COLOUR_22 {255,64,0}
  202. static __inline ULONG 
  203. dist_fn_22 ()
  204. {
  205.   return (red_dist[8] + green_dist[2] + blue_dist[0]);
  206. }
  207.  
  208. #define STD_COLOUR_23 {255,128,0}
  209. static __inline ULONG 
  210. dist_fn_23 ()
  211. {
  212.   return (red_dist[8] + green_dist[4] + blue_dist[0]);
  213. }
  214.  
  215. #define STD_COLOUR_24 {255,192,0}
  216. static __inline ULONG 
  217. dist_fn_24 ()
  218. {
  219.   return (red_dist[8] + green_dist[6] + blue_dist[0]);
  220. }
  221.  
  222. #define STD_COLOUR_25 {255,255,0}
  223. static __inline ULONG 
  224. dist_fn_25 ()
  225. {
  226.   return (red_dist[8] + green_dist[8] + blue_dist[0]);
  227. }
  228.  
  229. /*
  230.  * red-blues
  231.  */
  232. #define STD_COLOUR_26 {255,0,64}
  233. static __inline ULONG 
  234. dist_fn_26 ()
  235. {
  236.   return (red_dist[8] + green_dist[0] + blue_dist[2]);
  237. }
  238.  
  239. #define STD_COLOUR_27 {255,0,128}
  240. static __inline ULONG 
  241. dist_fn_27 ()
  242. {
  243.   return (red_dist[8] + green_dist[0] + blue_dist[4]);
  244. }
  245.  
  246. #define STD_COLOUR_28 {255,0,192}
  247. static __inline ULONG 
  248. dist_fn_28 ()
  249. {
  250.   return (red_dist[8] + green_dist[0] + blue_dist[6]);
  251. }
  252.  
  253. #define STD_COLOUR_29 {255,0,255}
  254. static __inline ULONG 
  255. dist_fn_29 ()
  256. {
  257.   return (red_dist[8] + green_dist[0] + blue_dist[8]);
  258. }
  259.  
  260. /*
  261.  * green-reds
  262.  */
  263. #define STD_COLOUR_30 {64,255,0}
  264. static __inline ULONG 
  265. dist_fn_30 ()
  266. {
  267.   return (red_dist[2] + green_dist[8] + blue_dist[0]);
  268. }
  269.  
  270. #define STD_COLOUR_31 {128,255,0}
  271. static __inline ULONG 
  272. dist_fn_31 ()
  273. {
  274.   return (red_dist[4] + green_dist[8] + blue_dist[0]);
  275. }
  276.  
  277. #define STD_COLOUR_32 {192,255,0}
  278. static __inline ULONG 
  279. dist_fn_32 ()
  280. {
  281.   return (red_dist[6] + green_dist[8] + blue_dist[0]);
  282. }
  283.  
  284. /*
  285.  * green-blues
  286.  */
  287. #define STD_COLOUR_33 {0,255,64}
  288. static __inline ULONG 
  289. dist_fn_33 ()
  290. {
  291.   return (red_dist[0] + green_dist[8] + blue_dist[2]);
  292. }
  293.  
  294. #define STD_COLOUR_34 {0,255,128}
  295. static __inline ULONG 
  296. dist_fn_34 ()
  297. {
  298.   return (red_dist[0] + green_dist[8] + blue_dist[4]);
  299. }
  300.  
  301. #define STD_COLOUR_35 {0,255,192}
  302. static __inline ULONG 
  303. dist_fn_35 ()
  304. {
  305.   return (red_dist[0] + green_dist[8] + blue_dist[6]);
  306. }
  307.  
  308. #define STD_COLOUR_36 {0,255,255}
  309. static __inline ULONG 
  310. dist_fn_36 ()
  311. {
  312.   return (red_dist[0] + green_dist[8] + blue_dist[8]);
  313. }
  314.  
  315. /*
  316.  * blue-reds
  317.  */
  318. #define STD_COLOUR_37 {64,255,0}
  319. static __inline ULONG 
  320. dist_fn_37 ()
  321. {
  322.   return (red_dist[2] + green_dist[8] + blue_dist[0]);
  323. }
  324.  
  325. #define STD_COLOUR_38 {128,255,0}
  326. static __inline ULONG 
  327. dist_fn_38 ()
  328. {
  329.   return (red_dist[4] + green_dist[8] + blue_dist[0]);
  330. }
  331.  
  332. #define STD_COLOUR_39 {192,255,0}
  333. static __inline ULONG 
  334. dist_fn_39 ()
  335. {
  336.   return (red_dist[6] + green_dist[8] + blue_dist[0]);
  337. }
  338.  
  339. /*
  340.  * blue-greens
  341.  */
  342. #define STD_COLOUR_40 {0,64,255}
  343. static __inline ULONG 
  344. dist_fn_40 ()
  345. {
  346.   return (red_dist[0] + green_dist[2] + blue_dist[8]);
  347. }
  348.  
  349. #define STD_COLOUR_41 {0,128,255}
  350. static __inline ULONG 
  351. dist_fn_41 ()
  352. {
  353.   return (red_dist[0] + green_dist[4] + blue_dist[8]);
  354. }
  355.  
  356. #define STD_COLOUR_42 {0,192,255}
  357. static __inline ULONG 
  358. dist_fn_42 ()
  359. {
  360.   return (red_dist[0] + green_dist[6] + blue_dist[8]);
  361. }
  362.  
  363. /*
  364.  * red green blue
  365.  */
  366. #define STD_COLOUR_43 {255,255,64}
  367. static __inline ULONG 
  368. dist_fn_43 ()
  369. {
  370.   return (red_dist[8] + green_dist[8] + blue_dist[2]);
  371. }
  372.  
  373. #define STD_COLOUR_44 {255,255,128}
  374. static __inline ULONG 
  375. dist_fn_44 ()
  376. {
  377.   return (red_dist[8] + green_dist[8] + blue_dist[4]);
  378. }
  379.  
  380. /*
  381.  * red blue green
  382.  */
  383. #define STD_COLOUR_45 {255,64,255}
  384. static __inline ULONG 
  385. dist_fn_45 ()
  386. {
  387.   return (red_dist[8] + green_dist[2] + blue_dist[8]);
  388. }
  389.  
  390. #define STD_COLOUR_46 {255,128,255}
  391. static __inline ULONG 
  392. dist_fn_46 ()
  393. {
  394.   return (red_dist[8] + green_dist[4] + blue_dist[8]);
  395. }
  396.  
  397. /*
  398.  * green blue red
  399. */
  400. #define STD_COLOUR_47 {64,255,255}
  401. static __inline ULONG 
  402. dist_fn_47 ()
  403. {
  404.   return (red_dist[2] + green_dist[8] + blue_dist[8]);
  405. }
  406.  
  407. #define STD_COLOUR_48 {128,255,255}
  408. static __inline ULONG 
  409. dist_fn_48 ()
  410. {
  411.   return (red_dist[4] + green_dist[8] + blue_dist[8]);
  412. }
  413.  
  414.  
  415. static std_pal_type standard_palette[48][3] =
  416. {
  417.   STD_COLOUR_01, STD_COLOUR_02, STD_COLOUR_03, STD_COLOUR_04, STD_COLOUR_05,
  418.   STD_COLOUR_06, STD_COLOUR_07, STD_COLOUR_08, STD_COLOUR_09, STD_COLOUR_10,
  419.   STD_COLOUR_11, STD_COLOUR_12, STD_COLOUR_13, STD_COLOUR_14, STD_COLOUR_15,
  420.   STD_COLOUR_16, STD_COLOUR_17, STD_COLOUR_18, STD_COLOUR_19, STD_COLOUR_20,
  421.   STD_COLOUR_21, STD_COLOUR_22, STD_COLOUR_23, STD_COLOUR_24, STD_COLOUR_25,
  422.   STD_COLOUR_26, STD_COLOUR_27, STD_COLOUR_28, STD_COLOUR_29, STD_COLOUR_30,
  423.   STD_COLOUR_31, STD_COLOUR_32, STD_COLOUR_33, STD_COLOUR_34, STD_COLOUR_35,
  424.   STD_COLOUR_36, STD_COLOUR_37, STD_COLOUR_38, STD_COLOUR_39, STD_COLOUR_40,
  425.   STD_COLOUR_41, STD_COLOUR_42, STD_COLOUR_43, STD_COLOUR_44, STD_COLOUR_45,
  426.   STD_COLOUR_46, STD_COLOUR_47, STD_COLOUR_48};
  427.  
  428. /*
  429.  * StandardPalette() - If shared == FALSE allocate a set of 48 standard
  430.  * colours which may be shared by other programs. If shared == TRUE attemps
  431.  * to share those same colours.
  432.  */
  433. int
  434. StandardPalette (struct ViewPort * vp, UWORD shared)
  435. {
  436.   int i, error = 0;
  437.   if (shared)
  438.     {
  439.       for (i = 0; i < 48; i++)
  440.     {
  441.       if ((standard_pens[i] = ObtainBestPen (vp->ColorMap,
  442.                      ((ULONG)standard_palette[i][0] << 24),
  443.                      ((ULONG)standard_palette[i][1] << 24),
  444.                      ((ULONG)standard_palette[i][2] << 24),
  445.                          NULL)) == -1)
  446.         error++;
  447.     }
  448.     }
  449.   else
  450.     {
  451.       for (i = 0; i < 48; i++)
  452.     {
  453.       if ((standard_pens[i] = ObtainPen (vp->ColorMap,
  454.                          -1,
  455.                 ((ULONG)standard_palette[i][0] << 24),
  456.                 ((ULONG)standard_palette[i][1] << 24),
  457.                 ((ULONG)standard_palette[i][2] << 24),
  458.                          0L)) == -1)
  459.         error++;
  460.     }
  461.     }
  462.   return (error);
  463. }
  464.  
  465. /*
  466.  * ReleasePens() - Release the pens allocated by StandardPalette()
  467.  */
  468. VOID
  469. ReleasePens (struct ViewPort * vp)
  470. {
  471.   int i;
  472.   for (i = 0; i < 48; i++)
  473.     {
  474.       if (standard_pens[i] != -1)
  475.     ReleasePen (vp->ColorMap, standard_pens[i]);
  476.     }
  477.  
  478. }
  479.  
  480. #define sqr(n) ((n)*(n))
  481.  
  482.  
  483. /*
  484.  * set_dist()
  485.  * The input colour needs to be compared with all the standard colours to
  486.  * find the best match.  Here we calculate the square of the distance to
  487.  * the various colour components used in the standard palette.
  488.  */
  489. static VOID
  490. set_dist (const UBYTE red, const UBYTE green, const UBYTE blue,
  491.       const ULONG * prev, const USHORT useprev)
  492. {
  493.   if ((!useprev) || (red != prev[0]))
  494.     {
  495.       red_dist[0] = sqr (red);
  496.       red_dist[1] = sqr (32 - red);
  497.       red_dist[2] = sqr (64 - red);
  498.       red_dist[3] = sqr (96 - red);
  499.       red_dist[4] = sqr (128 - red);
  500.       red_dist[5] = sqr (160 - red);
  501.       red_dist[6] = sqr (192 - red);
  502.       red_dist[7] = sqr (224 - red);
  503.       red_dist[8] = sqr (255 - red);
  504.     }
  505.   if ((!useprev) || (green != prev[1]))
  506.     {
  507.       green_dist[0] = sqr (green);
  508.       green_dist[1] = sqr (32 - green);
  509.       green_dist[2] = sqr (64 - green);
  510.       green_dist[3] = sqr (96 - green);
  511.       green_dist[4] = sqr (128 - green);
  512.       green_dist[5] = sqr (160 - green);
  513.       green_dist[6] = sqr (192 - green);
  514.       green_dist[7] = sqr (224 - green);
  515.       green_dist[8] = sqr (255 - green);
  516.     }
  517.   if ((!useprev) || (blue != prev[2]))
  518.     {
  519.       blue_dist[0] = sqr (blue);
  520.       blue_dist[1] = sqr (32 - blue);
  521.       blue_dist[2] = sqr (64 - blue);
  522.       blue_dist[3] = sqr (96 - blue);
  523.       blue_dist[4] = sqr (128 - blue);
  524.       blue_dist[5] = sqr (160 - blue);
  525.       blue_dist[6] = sqr (192 - blue);
  526.       blue_dist[7] = sqr (224 - blue);
  527.       blue_dist[8] = sqr (255 - blue);
  528.     }
  529. }
  530.  
  531. /*
  532.  * Pen number returns the pen number needed to best represent the pixel. prev
  533.  * is set to the actual colour used. So in normal use can be left alone.
  534.  */
  535. static UBYTE
  536. pen_number (const UBYTE red, const UBYTE green, const UBYTE blue,
  537.         ULONG * prev, const USHORT useprev)
  538. {
  539.   register ULONG dist;
  540.   ULONG min_dist = 0xFFFFFFFF;
  541.   ULONG pen;
  542.  
  543. #ifdef MAX_HAMSLIP
  544.   USHORT hamslip;
  545.  
  546.   if (!useprev)
  547.     hamslip = 0;
  548.   else if (hamslip > MAX_HAMSLIP)
  549.     useprev = 0;
  550.   /* hamslip gets set to zero later */
  551. #endif
  552.  
  553.   set_dist (red, green, blue, prev, useprev);
  554.  
  555. #if USE_STD_COLOURS
  556.   /*
  557.    * Use the __inline functions to find the best colour match.
  558.    */
  559.   min_dist = dist_fn_01 ();
  560.   pen = 0;
  561.  
  562.   if ((dist = dist_fn_02 ()) < min_dist)
  563.     {
  564.       min_dist = dist;
  565.       pen = 1;
  566.     }
  567.   if ((dist = dist_fn_03 ()) < min_dist)
  568.     {
  569.       min_dist = dist;
  570.       pen = 2;
  571.     }
  572.   if ((dist = dist_fn_04 ()) < min_dist)
  573.     {
  574.       min_dist = dist;
  575.       pen = 3;
  576.     }
  577.   if ((dist = dist_fn_05 ()) < min_dist)
  578.     {
  579.       min_dist = dist;
  580.       pen = 4;
  581.     }
  582.   if ((dist = dist_fn_06 ()) < min_dist)
  583.     {
  584.       min_dist = dist;
  585.       pen = 5;
  586.     }
  587.   if ((dist = dist_fn_07 ()) < min_dist)
  588.     {
  589.       min_dist = dist;
  590.       pen = 6;
  591.     }
  592.   if ((dist = dist_fn_08 ()) < min_dist)
  593.     {
  594.       min_dist = dist;
  595.       pen = 7;
  596.     }
  597.   if ((dist = dist_fn_09 ()) < min_dist)
  598.     {
  599.       min_dist = dist;
  600.       pen = 8;
  601.     }
  602.   if ((dist = dist_fn_10 ()) < min_dist)
  603.     {
  604.       min_dist = dist;
  605.       pen = 9;
  606.     }
  607.   if ((dist = dist_fn_11 ()) < min_dist)
  608.     {
  609.       min_dist = dist;
  610.       pen = 10;
  611.     }
  612.   if ((dist = dist_fn_12 ()) < min_dist)
  613.     {
  614.       min_dist = dist;
  615.       pen = 11;
  616.     }
  617.   if ((dist = dist_fn_13 ()) < min_dist)
  618.     {
  619.       min_dist = dist;
  620.       pen = 12;
  621.     }
  622.   if ((dist = dist_fn_14 ()) < min_dist)
  623.     {
  624.       min_dist = dist;
  625.       pen = 13;
  626.     }
  627.   if ((dist = dist_fn_15 ()) < min_dist)
  628.     {
  629.       min_dist = dist;
  630.       pen = 14;
  631.     }
  632.   if ((dist = dist_fn_16 ()) < min_dist)
  633.     {
  634.       min_dist = dist;
  635.       pen = 15;
  636.     }
  637.   if ((dist = dist_fn_17 ()) < min_dist)
  638.     {
  639.       min_dist = dist;
  640.       pen = 16;
  641.     }
  642.   if ((dist = dist_fn_18 ()) < min_dist)
  643.     {
  644.       min_dist = dist;
  645.       pen = 17;
  646.     }
  647.   if ((dist = dist_fn_19 ()) < min_dist)
  648.     {
  649.       min_dist = dist;
  650.       pen = 18;
  651.     }
  652.   if ((dist = dist_fn_20 ()) < min_dist)
  653.     {
  654.       min_dist = dist;
  655.       pen = 19;
  656.     }
  657.   if ((dist = dist_fn_21 ()) < min_dist)
  658.     {
  659.       min_dist = dist;
  660.       pen = 20;
  661.     }
  662.   if ((dist = dist_fn_22 ()) < min_dist)
  663.     {
  664.       min_dist = dist;
  665.       pen = 21;
  666.     }
  667.   if ((dist = dist_fn_23 ()) < min_dist)
  668.     {
  669.       min_dist = dist;
  670.       pen = 22;
  671.     }
  672.   if ((dist = dist_fn_24 ()) < min_dist)
  673.     {
  674.       min_dist = dist;
  675.       pen = 23;
  676.     }
  677.   if ((dist = dist_fn_25 ()) < min_dist)
  678.     {
  679.       min_dist = dist;
  680.       pen = 24;
  681.     }
  682.   if ((dist = dist_fn_26 ()) < min_dist)
  683.     {
  684.       min_dist = dist;
  685.       pen = 25;
  686.     }
  687.   if ((dist = dist_fn_27 ()) < min_dist)
  688.     {
  689.       min_dist = dist;
  690.       pen = 26;
  691.     }
  692.   if ((dist = dist_fn_28 ()) < min_dist)
  693.     {
  694.       min_dist = dist;
  695.       pen = 27;
  696.     }
  697.   if ((dist = dist_fn_29 ()) < min_dist)
  698.     {
  699.       min_dist = dist;
  700.       pen = 28;
  701.     }
  702.   if ((dist = dist_fn_30 ()) < min_dist)
  703.     {
  704.       min_dist = dist;
  705.       pen = 29;
  706.     }
  707.   if ((dist = dist_fn_31 ()) < min_dist)
  708.     {
  709.       min_dist = dist;
  710.       pen = 30;
  711.     }
  712.   if ((dist = dist_fn_32 ()) < min_dist)
  713.     {
  714.       min_dist = dist;
  715.       pen = 31;
  716.     }
  717.   if ((dist = dist_fn_33 ()) < min_dist)
  718.     {
  719.       min_dist = dist;
  720.       pen = 32;
  721.     }
  722.   if ((dist = dist_fn_34 ()) < min_dist)
  723.     {
  724.       min_dist = dist;
  725.       pen = 33;
  726.     }
  727.   if ((dist = dist_fn_35 ()) < min_dist)
  728.     {
  729.       min_dist = dist;
  730.       pen = 34;
  731.     }
  732.   if ((dist = dist_fn_36 ()) < min_dist)
  733.     {
  734.       min_dist = dist;
  735.       pen = 35;
  736.     }
  737.   if ((dist = dist_fn_37 ()) < min_dist)
  738.     {
  739.       min_dist = dist;
  740.       pen = 36;
  741.     }
  742.   if ((dist = dist_fn_38 ()) < min_dist)
  743.     {
  744.       min_dist = dist;
  745.       pen = 37;
  746.     }
  747.   if ((dist = dist_fn_39 ()) < min_dist)
  748.     {
  749.       min_dist = dist;
  750.       pen = 38;
  751.     }
  752.   if ((dist = dist_fn_40 ()) < min_dist)
  753.     {
  754.       min_dist = dist;
  755.       pen = 39;
  756.     }
  757.   if ((dist = dist_fn_41 ()) < min_dist)
  758.     {
  759.       min_dist = dist;
  760.       pen = 40;
  761.     }
  762.   if ((dist = dist_fn_42 ()) < min_dist)
  763.     {
  764.       min_dist = dist;
  765.       pen = 41;
  766.     }
  767.   if ((dist = dist_fn_43 ()) < min_dist)
  768.     {
  769.       min_dist = dist;
  770.       pen = 42;
  771.     }
  772.   if ((dist = dist_fn_44 ()) < min_dist)
  773.     {
  774.       min_dist = dist;
  775.       pen = 43;
  776.     }
  777.   if ((dist = dist_fn_45 ()) < min_dist)
  778.     {
  779.       min_dist = dist;
  780.       pen = 44;
  781.     }
  782.   if ((dist = dist_fn_46 ()) < min_dist)
  783.     {
  784.       min_dist = dist;
  785.       pen = 45;
  786.     }
  787.   if ((dist = dist_fn_47 ()) < min_dist)
  788.     {
  789.       min_dist = dist;
  790.       pen = 46;
  791.     }
  792.   if ((dist = dist_fn_48 ()) < min_dist)
  793.     {
  794.       min_dist = dist;
  795.       pen = 47;
  796.     }
  797. #else
  798.   pen = 0;
  799. #endif
  800.  
  801.   if (useprev)
  802.     {
  803.       register ULONG red_dist_pre, green_dist_pre, blue_dist_pre;
  804.  
  805.       red_dist_pre = sqr (red - prev[0]);
  806.       green_dist_pre = sqr (green - prev[1]);
  807.       blue_dist_pre = sqr (blue - prev[2]);
  808.  
  809.       if ((dist = green_dist_pre + blue_dist_pre) < min_dist)
  810.     {
  811.       min_dist = dist;
  812.       pen = 101;
  813.     }
  814.       if ((dist = red_dist_pre + blue_dist_pre) < min_dist)
  815.     {
  816.       min_dist = dist;
  817.       pen = 102;
  818.     }
  819.       if ((dist = red_dist_pre + green_dist_pre) < min_dist)
  820.     {
  821.       pen = 103;
  822.     }
  823.     }
  824.  
  825.   /*
  826.    * Convert pen number to true pen number 
  827.    */
  828.   switch (pen)
  829.     {
  830.     case 101:
  831.       /* Modify Red */
  832.       pen = (0x2 << 6) | (red >> 2);
  833.       prev[0] = red;
  834. #ifdef MAX_HAMSLIP
  835.       hamslip++;
  836. #endif
  837.       break;
  838.     case 102:
  839.       pen = (0x3 << 6) | (green >> 2);
  840.       prev[1] = green;
  841. #ifdef MAX_HAMSLIP
  842.       hamslip++;
  843. #endif
  844.       break;
  845.     case 103:
  846.       pen = (0x1 << 6) | (blue >> 2);
  847.       prev[2] = blue;
  848. #ifdef MAX_HAMSLIP
  849.       hamslip++;
  850. #endif
  851.       break;
  852.     default:
  853.       prev[0] = standard_palette[pen][0];
  854.       prev[1] = standard_palette[pen][1];
  855.       prev[2] = standard_palette[pen][2];
  856. #ifdef MAX_HAMSLIP
  857.       hamslip = 0;
  858. #endif
  859.       pen = standard_pens[pen];
  860.     }
  861.  
  862.   return ((UBYTE) pen);
  863. }
  864.  
  865. __regargs VOID
  866. WritePixelArray24 (struct RastPort * rp, const UWORD xstart,
  867.            const UWORD ystart, const UWORD width, const UWORD height,
  868.            UBYTE r[], UBYTE g[], UBYTE b[],
  869.            UBYTE * pen_array, struct RastPort * temprp)
  870. {
  871.   int x, y;
  872.   ULONG prev[3];        /* Used by pen_number to store the previous
  873.                  * pixel colour in 32,32,32 format. */
  874.   UBYTE *rptr = pen_array;
  875.  
  876.   for (y = 0; y < height; y++)
  877.     for (x = 0; x < width; x++)
  878.       *rptr++ = pen_number (*r++, *g++, *b++, prev, x);
  879.  
  880.   WritePixelArray8 (rp, xstart, ystart, xstart + width - 1, ystart + height - 1,
  881.             pen_array, temprp);
  882. }
  883.  
  884. __regargs VOID
  885. WritePixel24 (struct RastPort * rp, const UWORD xcoord,
  886.         const UWORD ycoord, const UBYTE r, const UBYTE g, const UBYTE b)
  887. {
  888.   UBYTE nextr, nextg, nextb;
  889.   USHORT prev_pen, old_pen, next_pen, new_pen;
  890.  
  891.   prev_pen = ReadPixel (rp, xcoord - 1, ycoord);
  892.   old_pen = ReadPixel (rp, xcoord, ycoord);
  893.   next_pen = ReadPixel (rp, xcoord + 1, ycoord);
  894.   /* Could use ReadPixelLine() */
  895.  
  896.   if (next_pen > 64)
  897.     {
  898.       /* Need to fix next. */
  899.       if ((prev_pen < 64) || (old_pen < 64))
  900.     {
  901.       /* simple */
  902.     }
  903.       else
  904.     {
  905.       /* take a guess at its value */
  906.       nextr = 0;
  907.       nextg = 0;
  908.       nextb = 0;
  909.       switch (prev_pen >> 6)
  910.         {
  911.         case 1:
  912.           nextb += prev_pen << 2;
  913.           break;
  914.         case 2:
  915.           nextr += prev_pen << 2;
  916.           break;
  917.         case 3:
  918.           nextg += prev_pen << 2;
  919.           break;
  920.         }
  921.       switch (old_pen >> 6)
  922.         {
  923.         case 1:
  924.           nextb += prev_pen << 2;
  925.           break;
  926.         case 2:
  927.           nextr += prev_pen << 2;
  928.           break;
  929.         case 3:
  930.           nextg += prev_pen << 2;
  931.           break;
  932.         }
  933.       switch (next_pen >> 6)
  934.         {
  935.         case 1:
  936.           nextb += prev_pen << 2;
  937.           break;
  938.         case 2:
  939.           nextr += prev_pen << 2;
  940.           break;
  941.         case 3:
  942.           nextg += prev_pen << 2;
  943.           break;
  944.         }
  945.     }
  946.     }
  947. }
  948.